
include config.mk

LIB_DIR = lib
INC_DIR = src
DAT_DIR = share
SRC_DIR = src

HAVE_PYTHON = @HAVE_PYTHON@

HAVE_DOCKER = @HAVE_DOCKER@
DOCKER_REGISTRY ?= ledatelescope
DOCKER_IMAGE_NAME ?= bifrost
DOCKER_TAG ?= $(LIBBIFROST_MAJOR).$(LIBBIFROST_MINOR)
DOCKER_CUDA_VERSION ?= 12.6.3
DOCKER_UBUNTU_VERSION ?= 22.04
DOCKER_GPU_ARCHS ?=
DOCKER_BUILD_DOCS ?= 0

CAN_BUILD_CXX_DOCS = @HAVE_CXX_DOCS@
CAN_BUILD_PYTHON_DOCS = @HAVE_PYTHON_DOCS@

BIFROST_PYTHON_DIR = python

all: libbifrost python
.PHONY: all

libbifrost:
	$(MAKE) -C $(SRC_DIR) all
.PHONY: libbifrost

check:
ifeq ($(HAVE_PYTHON),1)
	MYPYPATH=$(BIFROST_PYTHON_DIR) mypy --follow-imports=silent \
	    python/bifrost/blocks/detect.py \
	    python/bifrost/blocks/quantize.py \
	    python/bifrost/blocks/unpack.py \
	    python/bifrost/sigproc.py \
	    python/bifrost/sigproc2.py \
	    test/test_sigproc.py \
	    testbench/test_fft_detect.py
endif
.PHONY: check

test:
	#$(MAKE) -C $(SRC_DIR) test
ifeq ($(HAVE_PYTHON),1)
	cd test && ./download_test_data.sh ; @PYTHON@ -m unittest discover -v
endif
.PHONY: test
clean:
ifeq ($(HAVE_PYTHON),1)
	$(MAKE) -C $(BIFROST_PYTHON_DIR) clean || true
endif
	$(MAKE) -C $(SRC_DIR) clean
.PHONY: clean
install: $(INSTALL_LIB_DIR)/$(LIBBIFROST_SO_MAJ_MIN) $(INSTALL_INC_DIR)/$(BIFROST_NAME) $(INSTALL_DAT_DIR)/$(BIFROST_NAME) $(INSTALL_LIB_DIR)/pkgconfig
ifeq ($(HAVE_PYTHON),1)
	$(MAKE) -C $(BIFROST_PYTHON_DIR) install
endif
	@echo "Libraries have been installed in:"
	@echo "  $(INSTALL_LIB_DIR)"
	@echo ""
	@echo "If you ever happen to want to link against installed libraries"
	@echo "in a given directory, LIBDIR, you must either use libtool, and"
	@echo "specify the full pathname of the library, or use the '-LLIBDIR'"
	@echo "flag during linking and do at least one of the following:"
	@echo "  - add LIBDIR to the 'LD_LIBRARY_PATH' environment variable"
	@echo "    during execution"
	@echo "  - add LIBDIR to the 'LD_RUN_PATH' environment variable"
	@echo "    during linking"
	@echo "  - use the '-Wl,-rpath -Wl,LIBDIR' linker flag"
	@echo "  - have your system administrator add LIBDIR to '/etc/ld.so.conf'"
	@echo ""
	@echo "See any operating system documentation about shared libraries for"
	@echo "more information, such as the ld(1) and ld.so(8) manual pages."
.PHONY: install
uninstall:
	rm -f $(INSTALL_LIB_DIR)/$(LIBBIFROST_SO)
	rm -f $(INSTALL_LIB_DIR)/$(LIBBIFROST_SO_MAJ)
	rm -f $(INSTALL_LIB_DIR)/$(LIBBIFROST_SO_MAJ_MIN)
	rm -rf $(INSTALL_INC_DIR)/bifrost/
	rm -rf $(INSTALL_DAT_DIR)/bifrost/
	rm -f $(INSTALL_LIB_DIR)/pkgconfig/bifrost.pc
ifeq ($(HAVE_PYTHON),1)
	$(MAKE) -C $(BIFROST_PYTHON_DIR) uninstall
endif
.PHONY: uninstall

doc: $(INC_DIR)/bifrost/*.h Doxyfile docs/source/*.rst docs/source/*.py
ifeq ($(CAN_BUILD_CXX_DOCS),1)
	@DX_DOXYGEN@ Doxyfile
endif
ifeq ($(CAN_BUILD_PYTHON_DOCS),1)
	$(MAKE) -C docs singlehtml
endif
.PHONY: doc

python: libbifrost
ifeq ($(HAVE_PYTHON),1)
	$(MAKE) -C $(BIFROST_PYTHON_DIR) build
endif
.PHONY: python

# Bifrost-less GPU Docker build
docker-base:
ifeq ($(HAVE_DOCKER),1)
	docker build --pull \
		--build-arg CUDA_VERSION=$(DOCKER_CUDA_VERSION) \
		--build-arg UBUNTU_VERSION=$(DOCKER_UBUNTU_VERSION) \
		--build-arg BUILD_TYPE=gpu \
		--build-arg GPU_ARCHS="$(DOCKER_GPU_ARCHS)" \
		--build-arg BUILD_DOCS=$(DOCKER_BUILD_DOCS) \
		--target=base \
		-f Dockerfile \
		-t $(DOCKER_REGISTRY)/$(DOCKER_IMAGE_NAME)-base:$(DOCKER_TAG) \
		-t $(DOCKER_REGISTRY)/$(DOCKER_IMAGE_NAME)-base:latest .
endif
.PHONY: docker-base

# GPU Docker build
docker:
ifeq ($(HAVE_DOCKER),1)
	docker build --pull \
		--build-arg CUDA_VERSION=$(DOCKER_CUDA_VERSION) \
		--build-arg UBUNTU_VERSION=$(DOCKER_UBUNTU_VERSION) \
		--build-arg BUILD_TYPE=gpu \
		--build-arg GPU_ARCHS="$(DOCKER_GPU_ARCHS)" \
		--build-arg BUILD_DOCS=0 \
		-f Dockerfile \
		-t $(DOCKER_REGISTRY)/$(DOCKER_IMAGE_NAME):$(DOCKER_TAG) \
		-t $(DOCKER_REGISTRY)/$(DOCKER_IMAGE_NAME):latest .
endif
.PHONY: docker

# Bifrost-less CPU-only Docker build
docker-base-cpu:
ifeq ($(HAVE_DOCKER),1)
	docker build --pull \
		--build-arg UBUNTU_VERSION=$(DOCKER_UBUNTU_VERSION) \
		--build-arg BUILD_TYPE=cpu \
		--build-arg BUILD_DOCS=$(DOCKER_BUILD_DOCS) \
		--target=base \
		-f Dockerfile \
		-t $(DOCKER_REGISTRY)/$(DOCKER_IMAGE_NAME)-base-cpu:$(DOCKER_TAG) \
		-t $(DOCKER_REGISTRY)/$(DOCKER_IMAGE_NAME)-base-cpu:latest .
endif
.PHONY: docker-base-cpu

# CPU-only Docker build
docker-cpu:
ifeq ($(HAVE_DOCKER),1)
	docker build --pull \
		--build-arg UBUNTU_VERSION=$(DOCKER_UBUNTU_VERSION) \
		--build-arg BUILD_TYPE=cpu \
		--build-arg BUILD_DOCS=$(DOCKER_BUILD_DOCS) \
		-f Dockerfile \
		-t $(DOCKER_REGISTRY)/$(DOCKER_IMAGE_NAME)-cpu:$(DOCKER_TAG) \
		-t $(DOCKER_REGISTRY)/$(DOCKER_IMAGE_NAME)-cpu:latest .
endif
.PHONY: docker-cpu

# TODO: Consider adding a mode 'develop=1' that makes symlinks instead of copying
#         the library and headers.

$(INSTALL_LIB_DIR)/$(LIBBIFROST_SO_MAJ_MIN): $(LIB_DIR)/$(LIBBIFROST_SO_MAJ_MIN)
	mkdir -p $(INSTALL_LIB_DIR)
	cp $< $@
	ln -f -s $(LIBBIFROST_SO_MAJ_MIN) $(INSTALL_LIB_DIR)/$(LIBBIFROST_SO).$(LIBBIFROST_MAJOR)
	ln -f -s $(LIBBIFROST_SO_MAJ_MIN) $(INSTALL_LIB_DIR)/$(LIBBIFROST_SO)

$(INSTALL_INC_DIR)/bifrost: $(INC_DIR)/bifrost/*.h #$(INC_DIR)/bifrost/*.hpp
	mkdir -p $@
	cp $? $@/

$(INSTALL_DAT_DIR)/bifrost: $(DAT_DIR)/*.m4
	mkdir -p $@
	cp $? $@/

$(INSTALL_LIB_DIR)/pkgconfig: $(DAT_DIR)/*.pc
	mkdir -p $@
	cp $? $@/
